package com.ruoyi.project.common;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.excel.EasyExcel;
import com.ruoyi.common.utils.file.ZipUtils;
import com.ruoyi.project.easyexcel.AsyncTask.ExcelTask;
import com.ruoyi.project.easyexcel.ExcelUtils;
import com.ruoyi.project.easyexcel.ExportExcelHeader;
import com.ruoyi.project.easyexcel.UserImportExcelVO;
import com.ruoyi.project.system.domain.Study;
import com.ruoyi.project.system.domain.xuqiu;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.RuoYiConfig;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.framework.web.domain.AjaxResult;
import org.springframework.web.servlet.ModelAndView;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipOutputStream;

/**
 * 通用请求处理
 *
 * @author ruoyi
 */
@RestController
@Api(value="CommonController",description="公共类")
public class CommonController
{
    private static final Logger log = LoggerFactory.getLogger(CommonController.class);

    @Autowired
    private ServerConfig serverConfig;

    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("common/download")
    @ApiOperation(value = "文件是否删除")
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
    {
        try
        {
            if (!FileUtils.isValidFilename(fileName))
            {
                throw new Exception(StringUtils.format("文件名称({})非法，不允许下载。 ", fileName));
            }
            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
            String filePath = RuoYiConfig.getDownloadPath() + fileName;

            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, realFileName));
            FileUtils.writeBytes(filePath, response.getOutputStream());
            if (delete)
            {
                FileUtils.deleteFile(filePath);
            }
        }
        catch (Exception e)
        {
            log.error("下载文件失败", e);
        }
    }

    /**
     * 通用上传请求
     */
    @PostMapping("/common/upload")
    @ApiOperation(value = "文件上传")
    public AjaxResult uploadFile(@RequestParam("file") MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            System.out.println("上传文件路径为"+filePath);
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);

            String url = serverConfig.getUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("fileName", fileName);
            ajax.put("url", url);
            return ajax;
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/common/download/resource")
    @ApiOperation(value = "本地资源通用下载")
    public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception
    {
        // 本地资源路径  https://code84.com/842393.html
        String localPath = RuoYiConfig.getProfile();
        System.out.println("localPath=============="+localPath);
        // 数据库资源地址
        String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
        //截取最后一个斜杠之后的内容也就是 下载的文件名称
        String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
        System.out.println("downloadName=============="+downloadName);
        //设置浏览器响应
        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition",
                //根据不同的浏览器设置文件下载名称的编码格式
                "attachment;fileName=" + FileUtils.setFileDownloadHeader(request, downloadName));
        FileUtils.writeBytes(downloadPath, response.getOutputStream());
    }

    @GetMapping("/common/download/resource22")
    @ApiOperation(value = "本地资源通用下载")
    public void downloadLocal(HttpServletResponse response) throws FileNotFoundException {
        // 下载本地文件
        String fileName = "胡云ddd.doc"; // 文件的默认保存名
        // 读到流中
        InputStream inStream = new FileInputStream("E:\\ulms\\web\\zx\\22.docx");// 文件的存放路径
        // 设置输出的格式
        response.reset();
        response.setContentType("bin");
        response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
        // 循环取出流中的数据
        byte[] b = new byte[100];
        int len;
        try {
            while ((len = inStream.read(b)) > 0) {
                response.getOutputStream().write(b, 0, len);
            }
            inStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/common/zipDownload")
    @ApiOperation(value = "zip下载")
    public void zipexport(HttpServletResponse response) throws IOException {

        List<File> files = new ArrayList<File>();
        files.add(new File("E:\\ulms\\web\\fileLee\\386094_1452478576863.doc"));
        files.add(new File("E:\\ulms\\web\\fileLee\\386094_1448002857447.doc"));
        String zipName = "hyq.zip";
        response.setHeader("Content-Disposition","attachment; filename="+new String(zipName.getBytes(),"iso-8859-1"));
        response.setContentType("APPLICATION/OCTET-STREAM");
        ZipOutputStream out = null;
        try {
             out = new ZipOutputStream(response.getOutputStream());
            if (CollectionUtils.isEmpty(files) == false) {
                for (int i = 0,size = files.size(); i < size; i++) {
                    ZipUtils.compress(files.get(i), out, "");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            out.close();
        }

    }

    @RequestMapping("/index")
    @ResponseBody
    public ModelAndView menu(){
        return new ModelAndView("index");
    }

    @PostMapping("common/test")
    @ResponseBody
    @ApiOperation(value = "导出用户确认信息表doc", httpMethod = "POST", produces = "application/json", notes = "导出用户确认信息表doc")
    public void usertest(HttpServletResponse response) throws IOException {
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassForTemplateLoading(this.getClass(), "/code");
        Template template = configuration.getTemplate("test.ftl");
        Map<String, Object> resultMap = new HashMap<>();

        //用户列表
        List<Study> studyList = new ArrayList<>();
        studyList.add(new Study("hyq", "root", "1", "user", "123456"));
        studyList.add(new Study("nihao", "123", "15", "admin", "12232"));
        resultMap.put("userInfoList", studyList);

        //需求确认表
        List<xuqiu> xuqiu = new ArrayList<>();
        xuqiu.add(new xuqiu("我的","deddd","sfsdfsdsd"));
        xuqiu.add(new xuqiu("dddeeeddd","sdfaewrwedfd","afsdwrwerwe"));
        resultMap.put("test", xuqiu);
        //通过if 标签控制是否显示
        resultMap.put("x", "nihao");


        OutputStream output = response.getOutputStream();
        String fileName = URLEncoder.encode("ExportWord_"+System.currentTimeMillis()+".doc", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename="+fileName);
        //定义下载的类型，标明是word文件
        response.setContentType("application/msword;charset=UTF-8");
        Writer out = new BufferedWriter(new OutputStreamWriter(output, "UTF-8"));
        try {
            template.process(resultMap, out);
            out.flush();
            out.close();
        } catch (TemplateException e) {
            e.printStackTrace();
        }

    }

    /**
     * EasyExcel复杂excel导出 合并表头，合并数据
     * @param response
     * @throws IOException
     */
    @GetMapping("/common/excel")
    @ApiOperation(value = "测试导出excel")
    public void exportJobLogExcel(HttpServletResponse response) throws IOException {
        ExportExcelHeader.exportJobLogExcel(response);
    }

    @Autowired
    ExportExcelHeader exportExcelHeader;

    /**
     * 大数据导出300w行数据
     * @param response
     * @throws IOException
     */
    @GetMapping("/common/maxExcel")
    @ApiOperation(value = "超大数据导出")
    public void exportExcelMax(HttpServletResponse response) throws IOException {
//        ExportExcelHeader.exportExcelMax(response);
        exportExcelHeader.exportExcelMax(response);
    }


    @PostMapping("common/importExcel")
    public void importExcel(@RequestParam("file") MultipartFile file) throws Exception {
        List<UserImportExcelVO> list = ExcelUtils.read(file, UserImportExcelVO.class);

    }

    /**
     * 异步导出excel
     * @param response
     * @throws IOException
     */
    @Autowired
    ExcelTask excelTask;

    @GetMapping("/common/excelasync")
    @ApiOperation(value = "测试导出excel")
    public String excelasync(HttpServletResponse response) throws IOException {
        excelTask.exportExcel(response);
        return "2";
    }


}
